/*
 * @Author: Joel
 * @Date: 2025-04-07 09:00:45
 * @LastEditors: Joel
 * @LastEditTime: 2025-05-25 17:54:15
 * @FilePath: /gd32f303cct6/usr/src/main.c
 * @Description:
 * Copyright (C) 2025 YiJiaLink, All Rights Reserved.
 * 2025-04-07 09:00:45
 */
#include "main.h"
#include "oled_picture.h"

/* 按键回调 */
static void button_callback(void *arg);

/* 蜂鸣器 */
static struct buzzer_func *buzzer_set;
static void buzzer_callback(void *arg);

/* rled */
static struct rled_func *rled_set;
static void rled_callback(void *arg);

/* 气泵 */
static struct pump_func *pump_set;

/* 电压检测 */
static struct detect_adc_func *detect_set;

/* 输出控制 */
static struct ctrl_func *ctrl_set;

/* oled功能 */
static struct oled_func *oled_set;
static void oled_callback(void *arg);

/* ems功能 */
static struct ems_func *ems_set;
static void ems_callback(void *arg);

/* usb功能 */
static struct usb_func *usb_set;

int main(void)
{
    systick_config();

    // NVIC配置 优先级分组 抢占2 响应2
    nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);

    /* rtt初始化打印 */
    SEGGER_RTT_Init();

    printf("\r\n===============================\r\n");
    printf("CK_SYS is %ld\r\n", rcu_clock_freq_get(CK_SYS));
    printf("CK_AHB is %ld\r\n", rcu_clock_freq_get(CK_AHB));
    printf("CK_APB1 is %ld\r\n", rcu_clock_freq_get(CK_APB1));
    printf("CK_APB2 is %ld\r\n", rcu_clock_freq_get(CK_APB2));

    /* 按键初始化 */
    button_all_init();

    /* buzzer */
    printf("buzzer_init\n");
    buzzer_set = buzzer_init();
    buzzer_set->init_buzzer();

    /* rled初始化 */
    printf("rled_init\n");
    rled_set = rled_init();
    rled_set->init_rled();

    /* 气泵初始化 */
    printf("pump_driver_init\n");
    pump_set = pump_driver_init();
    pump_set->init_pump();

    /* adc输入检测 */
    printf("detect_driver_init\n");
    detect_set = detect_driver_init();
    detect_set->detect_adc_init();

    /* 输出控制 */
    printf("ctrl_driver_init\n");
    ctrl_set = ctrl_driver_init();
    ctrl_set->device_init();

    /* oled功能 */
    printf("oled_driver_init\n");
    uint8_t trun_on = 0xAF;
    oled_set = oled_driver_init();
    oled_set->init_oled();
    oled_set->fill_oled();
    delay_1ms(5);
    oled_set->send_com(&trun_on, 1);
    oled_set->clear_oled();
    oled_set->dis_set();
    oled_set->clear_oled();

    /* ems功能 */
    // printf("ems_driver_init\n");
    // ems_set = ems_driver_init();
    // ems_set->init_ems();

    /* usb功能 */
    printf("usb_driver_init\n");
    // usb_set = cdc_acm_init();
    // usb_set->reset_usb();
    // usb_set->init_usb_cdc();
    // usb_set->connect_usb_cdc();
    /*  task定时器 */
    printf("timer_driver_init\n");
    User_Timer_Init();

    /* 按键处理进程300hz */
    User_Timer_Config(TIMERID0, 40, button_callback, NULL);

    /* rled处理进程 40Khz*/
    User_Timer_Config(TIMERID1, 2, rled_callback, NULL);

    /* 蜂鸣器处理进程 4Khz*/
    User_Timer_Config(TIMERID2, 13, buzzer_callback, NULL);

    /* oled处理进程 150hz*/
    User_Timer_Config(TIMERID3, 320, oled_callback, NULL);

    /* ems处理进程 15hz*/
    User_Timer_Config(TIMERID4, 3200, ems_callback, NULL);

    User_Timer_Start(TIMERID0);
    User_Timer_Start(TIMERID1);
    // User_Timer_Start(TIMERID2);
    User_Timer_Start(TIMERID3);
    // User_Timer_Start(TIMERID4);
    printf("Build Date %s %s\r\n", __DATE__, __TIME__);
    printf("===============================\r\n");

    uint16_t duty = 0;
    uint8_t control_flag = 0;
    for (;;)
    {
        // pump_set->stop_pump();
        pump_set->run_pump(duty++);

        detect_set->adc_value[EMS_ADC] = detect_set->detect_result(EMS_ADC);
        printf("EMS_ADC=%d\n", detect_set->adc_value[EMS_ADC]);
        detect_set->adc_value[VBAT_ADC] = detect_set->detect_result(VBAT_ADC);
        printf("VBAT_ADC=%d\n", detect_set->adc_value[VBAT_ADC]);
        detect_set->adc_value[PUMP_ADC] = detect_set->detect_result(PUMP_ADC);
        printf("PUMP_ADC=%d\n", detect_set->adc_value[PUMP_ADC]);

        control_flag = !control_flag;
        ctrl_set->ctrl_run(PWR_CTRL, control_flag);

        /* 处理数据 */
        usb_set->run_cdc();

        printf("main_loop\n");
        delay_1ms(1000);
    }
    return 0;
}

static void button_callback(void *arg)
{
    static struct button_filter button_filter;
    static struct button_click button_click;

    struct usr_key *button_p = get_button_pressed();

    /* 电源键 */
    if (0 == button_p->power_key)
        ++button_filter.power_index;
    else
        button_filter.power_index = 0;
    if (KEY_FILTER_TIME < button_filter.power_index)
    {
        if ((KEY_FILTER_TIME + 2) == button_filter.power_index)
        {
            printf("power_key = %d\n", button_p->power_key);
            button_click.power_click++;
            /* 触发连击计时标志 */
            button_click.power_click_timer = 1;
        }
        else if (KEY_LONG_PRESSED_TIME == button_filter.power_index)
        {
            printf("power_key_long_pressed = %d\n", button_p->power_key);
        }
        else if (KEY_LONG_PRESSED_TIME + 1 == button_filter.power_index)
            /* 等待长按键释放 */
            button_filter.power_index = KEY_LONG_PRESSED_TIME;
    } /* 连击计时 */
    else if ((button_click.power_click_timer) && (!button_filter.power_index))
        button_click.power_click_timer++;
    /* 连击时间到获取按键结果 */
    if (KEY_CLICK_TIME <= button_click.power_click_timer)
    {
        printf(" button_click.power_click = %d\n", button_click.power_click);
        button_click.power_click_timer = 0;
        button_click.power_click = 0;
    }
    /* 方向上键 */
    if (0 == button_p->up_key)
        ++button_filter.up_index;
    else
        button_filter.up_index = 0;
    if (KEY_FILTER_TIME < button_filter.up_index)
    {
        if ((KEY_FILTER_TIME + 2) == button_filter.up_index)
        {
            printf("up_key = %d\n", button_p->up_key);
            button_click.up_click++;
            /* 触发连击计时标志 */
            button_click.up_click_timer = 1;
        }
        else if (KEY_LONG_PRESSED_TIME == button_filter.up_index)
        {
            printf("power_key_long_pressed = %d\n", button_p->up_key);
        }
        else if (KEY_LONG_PRESSED_TIME + 1 == button_filter.up_index)
            /* 等待长按键释放 */
            button_filter.up_index = KEY_LONG_PRESSED_TIME;
    } /* 连击计时 */
    else if ((button_click.up_click_timer) && (!button_filter.up_index))
        button_click.up_click_timer++;
    /* 连击时间到获取按键结果 */
    if (KEY_CLICK_TIME <= button_click.up_click_timer)
    {
        printf(" button_click.up_click = %d\n", button_click.up_click);
        button_click.up_click_timer = 0;
        button_click.up_click = 0;
    }

    /* 方向下键 */
    if (0 == button_p->down_key)
        ++button_filter.down_index;
    else
        button_filter.down_index = 0;
    if (KEY_FILTER_TIME < button_filter.down_index)
    {
        if ((KEY_FILTER_TIME + 2) == button_filter.down_index)
        {
            printf("down_key = %d\n", button_p->down_key);
            button_click.down_click++;
            /* 触发连击计时标志 */
            button_click.down_click_timer = 1;
        }
        else if (KEY_LONG_PRESSED_TIME == button_filter.down_index)
        {
            printf("down_key_long_pressed = %d\n", button_p->down_key);
        }
        else if (KEY_LONG_PRESSED_TIME + 1 == button_filter.down_index)
            /* 等待长按键释放 */
            button_filter.down_index = KEY_LONG_PRESSED_TIME;
    } /* 连击计时 */
    else if ((button_click.down_click_timer) && (!button_filter.down_index))
        button_click.down_click_timer++;
    /* 连击时间到获取按键结果 */
    if (KEY_CLICK_TIME <= button_click.down_click_timer)
    {
        printf(" down_click = %d\n", button_click.down_click);
        button_click.down_click_timer = 0;
        button_click.down_click = 0;
    }
    if (0 == button_p->confirm_key)
        printf("confirm_key = %d\n", button_p->confirm_key);
    if (button_p->charging_input)
        printf("charging_input = %d\n", button_p->charging_input);
    return;
}
/**
 * @func:
 * @description: 蜂鸣器回调
 * @param {void} *arg
 * @return {*}
 * @example:
 */
static void buzzer_callback(void *arg)
{

    /* 启动蜂鸣器4Khz */
    buzzer_set->run_buzzer();
    return;
}
/**
 * @func:
 * @description: rled处理回调
 * @param {void} *arg
 * @return {*}
 * @example:
 */
static void rled_callback(void *arg)
{
    static enum PWM_DUTY PWM_DUTY = DUTY75;
    /* 启动rled 13Khz */
    rled_set->run_rled(PWM_DUTY);
    return;
}
/**
 * @func:
 * @description: oled进程
 * @param {void} *arg
 * @return {*}
 * @example:
 */
static void oled_callback(void *arg)
{
    static int index;
    static enum PUMP_STATE PUMP_STATE = PUMP_OFF;
    static enum BAT_STATE BAT_STATE = BAT_EMPY;
    static enum TEMP_STATE TEMP_STATE = TEMP_OFF;
    static enum ALARM_STATE ALARM_STATE = ALARM_OFF;
    static enum LIGHT_STATE LIGHT_STATE = LIGHT_OFF;
    static enum NUM_STATE NUM_STATE = NUM_0;
    if (++index == 100)
    {
        if (++PUMP_STATE > PUMP_LEVEL3)
            PUMP_STATE = PUMP_OFF;
        set_pump_icon(PUMP_STATE);

        if (++BAT_STATE > BAT_FULL)
            BAT_STATE = BAT_EMPY;
        set_battery_icon(BAT_STATE);

        if (++TEMP_STATE > TEMP_LEVEL3)
            TEMP_STATE = TEMP_OFF;
        set_temp_icon(TEMP_STATE);

        ALARM_STATE = !ALARM_STATE;
        set_alarm_icon(ALARM_STATE);

        if (++LIGHT_STATE > LIGHT_LEVEL3)
            LIGHT_STATE = LIGHT_OFF;
        set_light_icon(LIGHT_STATE);

        if (++NUM_STATE > NUM_9)
            NUM_STATE = NUM_0;
        set_num_icon(NUM_STATE);

        index = 0;
        printf("oled_command\n");
    }
    return;
}
/**
 * @func:
 * @description: EMS坐垫进程
 * @param {void} *arg
 * @return {*}
 * @example:
 */
static void ems_callback(void *arg)
{
    static int index;
    if (index < 1599)
        ems_set->run_ems(EMS_PWM_BOOT, index);

    if (index == 1600)
    {
        ems_set->stop_pump(EMS_PWM_BOOT, 0);
    }
    else
        index += 20;
    return;
}